'''
Created on Jan 18, 2010

@author: christianp
'''
import copy
from math import ceil
from math import floor
from Extent import Extent
from TileInfo import TileInfo
from TileRange import TileRange
from Utilities import Utilities
from AxisInvertedY import AxisInvertedY


class TileSchema(object):
    
    name = ""
    url = ""
    src = ""
    extent = Extent(0,0,0.1,0.1)
    origin_x = 0.0
    origin_y = 0.0
    resolutions = []
    width = 0
    height = 0
    format = ""
    axis = ""
    
    extents = []
    
    #max_resolution = 1222.992452344
    
    #previousResolution = 0.0
    
    def __init__(self):
        '''tileschema'''
    
    def getHref(self):
        return self.url + self.name
    
    def getResolution(self, index):
        return self.resolutions[index][1]
    
    def getTilesInView1(self, extent, resolution):
        level = Utilities.getNearestLevel(self.resolutions, resolution)
        return self.getTilesInView2(extent, level)
    
    def getTilesInView2(self, extent, level):
        tiles = []
        axisInverted = AxisInvertedY()
        tileRange = axisInverted.worldToTile(extent, level, self)
        
        #print("TileSchema x:" + str(int(tileRange.getLastCol())))
        #print("TileSchema y:" + str(int(tileRange.getLastRow())))
        for x in range(int(tileRange.getFirstCol()), int(tileRange.getLastCol())):            
            for y in range(int(tileRange.getFirstRow()), int(tileRange.getLastRow())):
                tile = TileInfo()
                tile.extent = axisInverted.tileToWorld(TileRange(x,y,x,y), level, self)
                tile.key = (x,y,level)
                if (self.withinSchemaExtent(self.extent, tile.extent)):
                    tiles.append(tile)
        
        return tiles
    
    def getTilesRange(self, extent, resolution):
        level = Utilities.getNearestLevel(self.resolutions, resolution)
        axisInverted = AxisInvertedY()
        tile_range = axisInverted.worldToTile(extent, level, self)
        
        x = int(tile_range.getLastCol()) - int(tile_range.getFirstCol())
        y = int(tile_range.getLastRow()) - int(tile_range.getFirstRow())
        
        return (x, y)
    '''
    def getSmallerExtent1(self, extent, resolution, do_after, tiles):
        self.getSmallerExtent(tiles[0], tiles[1], resolution, extent, do_after, 4)
    
    def getSmallerExtent(self, col, row, resolution, extent, do_after, max_nr_tiles):
        
        maxX = int(ceil(col/max_nr_tiles))
        maxY = int(ceil(row/max_nr_tiles))
        
        width = extent.getWidth()/(col/max_nr_tiles)
        heigth = extent.getHeight()/(row/max_nr_tiles)
        
        minx = extent.getMinX()
        miny = extent.getMinY()
        maxx = minx + width
        maxy = miny + heigth
        
        for x in range(0, maxX):
            for y in range(0, maxY):
                if(maxx <= extent.getMaxX())and (maxy <= extent.getMaxY()):
                    newExtent = Extent(minx,miny,maxx,maxy)
                    do_after(newExtent, resolution)
                miny = maxy
                maxy += heigth
            
            minx = maxx
            maxx += width
        
        #do_after(extent, resolution)
    '''
    '''
    def containsExtent(self, exo):
        for e in self.extents:
            if exo == e:
                return True
        return False;
        '''
    '''
    def getExtentInTiles(self, col, row, resolution, extent):
        tiles = []
        smaller_extent = []
        axisInverted = AxisInvertedY()
        if (col >= self.nr_of_tiles) or (row >= self.nr_of_tiles):
            max_col = int(ceil(col / self.nr_of_tiles))
            max_row = int(ceil(row / self.nr_of_tiles))
            for x in range(0, max_col):
                for y in range(0, max_row):
                    min_x = x * self.nr_of_tiles
                    min_y = y * self.nr_of_tiles
                    max_x = min_x + self.nr_of_tiles
                    max_y = min_y + self.nr_of_tiles
                    extent = axisInverted.tileToWorld2(TileRange(min_x, min_y, max_x, max_y), resolution, self)
                    tiles.append(extent)
        else:
            tiles.append(extent)
        return tiles
        '''
    '''
    def getResolutionsBetween(self, start_resolution, end_resolution):
        resolutions = []
        for resolution in self.__resolutions:
            resolution = resolution[1]
            if (resolution <= start_resolution):
                if (resolution >= end_resolution):
                    resolutions.append(resolution)
        
        return resolutions
    '''
    '''
    def checkSmallerExtent(self, extent, level):
        axisInverted = AxisInvertedY()
        tile_range = axisInverted.worldToTile2(extent, level, self)
    '''
    def withinSchemaExtent(self, schema_extent, tile_extent):
        if not (tile_extent.isIntersecting(schema_extent)):
            return False
        
        extent = tile_extent.intersectsWith(schema_extent)
        return (extent.getArea() / tile_extent.getArea()) > 0.05
    
    def GetCopy(self):
        return copy.deepcopy(self)